package com.alks.common.utils;

import cn.hutool.core.date.LocalDateTimeUtil;

import javax.xml.crypto.Data;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author: chen
 * @date: 2024/12/21
 * @description: 对象转MAP
 */
public class ObjectToMapUtil {

    public static Map<String, Object> convert(Object obj) {
        return convert(obj, null, null);
    }

    public static Map<String, Object> convert(Object obj, String dateformat, Integer numberScale) {
        if (obj == null) {
            return null;
        }
        Map<String, Object> resultMap = new HashMap<>();
        if (obj instanceof Collection) {
            resultMap.put("list", handleCollection((Collection<?>) obj, dateformat, numberScale));
        } else {
            convertObjectToMap(obj, resultMap, dateformat, numberScale);
        }
        return resultMap;
    }

    private static void convertObjectToMap(Object obj, Map<String, Object> resultMap, String dateformat, Integer numberScale) {
        // 获取对象的所有字段
        Field[] fields = obj.getClass().getDeclaredFields();

        for (Field field : fields) {
//            field.setAccessible(true);  // 设置可访问性
            try {
                Method method = obj.getClass().getDeclaredMethod(toGetName(field.getName()));
                method.setAccessible(true);
                Object value = method.invoke(obj);

                if (value == null) {
                    resultMap.put(field.getName(), null);
                } else if (isPrimitiveOrWrapper(value)) {// 基本类型或包装类型
                    if (value instanceof BigDecimal && numberScale != null) {
                        resultMap.put(field.getName(), BigDecimalUtil.formatNumber((BigDecimal) value, numberScale));
                    } else if (value instanceof LocalDate) {
                        resultMap.put(field.getName(), LocalDateTimeUtil.format((LocalDate)value, dateformat));
                    } else if (value instanceof LocalDateTime) {
                        resultMap.put(field.getName(), LocalDateTimeUtil.format((LocalDateTime)value, dateformat));
                    } else {
                        resultMap.put(field.getName(), value);
                    }
                } else if (value instanceof String) {
                    resultMap.put(field.getName(), value);  // String 类型
                } else if (value instanceof Collection) {
                    resultMap.put(field.getName(), handleCollection((Collection<?>) value, dateformat, numberScale));  // 集合类型
                } else if (value.getClass().isArray()) {
                    resultMap.put(field.getName(), handleArray(value, dateformat, numberScale));  // 数组类型
                } else {
                    Map<String, Object> nestedMap = new HashMap<>();
                    convertObjectToMap(value, nestedMap, dateformat, numberScale);  // 递归处理嵌套对象
                    resultMap.put(field.getName(), nestedMap);
                }
            } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }

    private static String toGetName(String str) {
        if (str == null || str.isEmpty()) {
            return str; // 如果字符串为null或空，直接返回
        }
        if (str.length() == 1) {
            return str.toUpperCase(); // 如果只有一个字符，直接转为大写
        }
        // 将首字符大写，其他部分保持不变
        return "get" + str.substring(0, 1).toUpperCase() + str.substring(1);
    }

    // 判断是否为基本类型或其包装类型
    private static boolean isPrimitiveOrWrapper(Object value) {
        return value instanceof Number || value instanceof Boolean || value instanceof Character || value instanceof String || value instanceof LocalDate || value instanceof LocalDateTime;
    }

    // 处理集合类型
    private static List<Map<String, Object>> handleCollection(Collection<?> collection, String dateformat, Integer numberScale) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (Object item : collection) {
            Map<String, Object> itemMap = new HashMap<>();
            convertObjectToMap(item, itemMap, dateformat, numberScale);
            resultList.add(itemMap);
        }
        return resultList;
    }

    // 处理数组类型
    private static List<Map<String, Object>> handleArray(Object array, String dateformat, Integer numberScale) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        int length = java.lang.reflect.Array.getLength(array);
        for (int i = 0; i < length; i++) {
            Object item = java.lang.reflect.Array.get(array, i);
            Map<String, Object> itemMap = new HashMap<>();
            convertObjectToMap(item, itemMap, dateformat, numberScale);
            resultList.add(itemMap);
        }
        return resultList;
    }
}
